{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 动画绘图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using matplotlib backend: Qt5Agg\n"
     ]
    }
   ],
   "source": [
    "%matplotlib"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 更新数据方式\n",
    "    1.实现产生好数据，根据帧号进行选择\n",
    "    2.用生成器产生数据\n",
    "    3.帧号作为输入，利用函数计算对应数据\n",
    "#### 输出方式\n",
    "    1.plt.show()\n",
    "    2.anim.save：a.视频输出 b.gif输出"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 没有init()函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import matplotlib.animation as animation\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "def update_point(num):\n",
    "    fig_points.set_data(x[0:num], y[0:num])\n",
    "    return fig_points\n",
    "\n",
    "fig1 = plt.figure()\n",
    "num_point = 50\n",
    "x = np.random.rand(num_point)\n",
    "y = np.random.rand(num_point)\n",
    "fig_points, = plt.plot([], [], 'ro')\n",
    "\n",
    "plt.xlim(0, 1)\n",
    "plt.ylim(0, 1)\n",
    "\n",
    "anim = animation.FuncAnimation(fig1, update_point, frames=num_point, interval=10, repeat=True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 有init()函数，输出mp4，GIF"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 安装ImageMagick\n",
    "\n",
    "ImageMagick是一个类似于编码器的工具，下载地址：http://www.imagemagick.org/script/binary-releases.php \n",
    "\n",
    "#### 配置matplotlib\n",
    "\n",
    "    import matplotlib\n",
    "    matplotlib.matplotlib_fname()\n",
    "\n",
    "会输出类似一个路径，用文本文件打开这个文件，编辑末尾的：\n",
    "\n",
    "    animation.convert_path: '\"C:\\Program Files\\ImageMagick-7.0.4-Q16\\convert.exe\"'\n",
    "\n",
    "记得取消“animation.convert_path”前面的注释。这样应该就配置好了，接下来用一句话就可以导出gif：\n",
    "\n",
    "    anim.save('perceptron.gif', fps=2, writer='imagemagick')\n",
    "\n",
    "报错情况处理\n",
    "\n",
    "更改路径下：C:\\Python35\\Lib\\site-packages\\matplotlib下的__init__.py，\n",
    "\n",
    "或者 C:\\ProgramData\\Anaconda3\\Lib\\site-packages\\matplotlib 下 ，在1183行加一句：\n",
    "    # this is the instance used by the matplotlib classes\n",
    "    rcParams = rc_params()\n",
    "    rcParams['animation.convert_path'] = 'C:\\Program Files\\ImageMagick-7.0.4-Q16\\convert.exe'\n",
    "\n",
    "\n",
    "参照：\n",
    "http://www.hankcs.com/ml/using-matplotlib-and-imagemagick-to-realize-the-algorithm-visualization-and-gif-export.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'C:\\\\ProgramData\\\\Anaconda3\\\\lib\\\\site-packages\\\\matplotlib\\\\mpl-data\\\\matplotlibrc'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import matplotlib\n",
    "matplotlib.matplotlib_fname()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import matplotlib.animation as animation\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "def init():\n",
    "    fig_points.set_data([], [])\n",
    "    return fig_points\n",
    "\n",
    "def update(num):\n",
    "    fig_points.set_data(x[0:num], y[0:num])\n",
    "    return fig_points\n",
    "\n",
    "fig1 = plt.figure()\n",
    "num_point = 50\n",
    "x = np.random.rand(num_point)\n",
    "y = np.random.rand(num_point)\n",
    "fig_points, = plt.plot([], [], 'ro')\n",
    "\n",
    "plt.xlim(0, 1)\n",
    "plt.ylim(0, 1)\n",
    "\n",
    "anim = animation.FuncAnimation(fig1, update, frames=num_point, interval=10, repeat=True, \n",
    "                              init_func=init)\n",
    "# anim.save(\"anim1.mp4\")\n",
    "anim.save(\"anim1.gif\", writer=\"imagemagick\")\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.animation as animation\n",
    "\n",
    "\n",
    "def data_gen():\n",
    "    t=0\n",
    "    cnt = 0\n",
    "    while cnt < 200:\n",
    "        cnt += 1\n",
    "        t += 0.1\n",
    "        yield t, np.sin(2*np.pi*t) * np.exp(-t/10.)\n",
    "\n",
    "\n",
    "def init():\n",
    "    ax.set_ylim(-1.1, 1.1)\n",
    "    ax.set_xlim(0, 10)\n",
    "    line.set_data([], [])\n",
    "    return line,\n",
    "\n",
    "\n",
    "def update(datag):\n",
    "    # update the data\n",
    "    t, y = datag\n",
    "    xdata.append(t)\n",
    "    ydata.append(y)\n",
    "    line.set_data(xdata, ydata)\n",
    "    \n",
    "    if max(xdata)>10:\n",
    "        ax.set_xlim(max(xdata)-10, max(xdata))\n",
    "    return line,\n",
    "    \n",
    "    \n",
    "fig, ax = plt.subplots()\n",
    "line, = ax.plot([], [], lw=2)\n",
    "ax.grid()\n",
    "xdata, ydata = [], []\n",
    "\n",
    "ani = animation.FuncAnimation(fig, update, data_gen, interval=10,\n",
    "                              repeat=False, init_func=init)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np  \n",
    "from matplotlib import pyplot as plt  \n",
    "from matplotlib import animation  \n",
    "  \n",
    "# First set up the figure, the axis, and the plot element we want to animate  \n",
    "fig = plt.figure()  \n",
    "ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))  \n",
    "line, = ax.plot([], [], lw=2)  \n",
    "\n",
    "# initialization function: plot the background of each frame  \n",
    "def init():  \n",
    "    line.set_data([], [])  \n",
    "    return line,  \n",
    "\n",
    "# animation function.  This is called sequentially  \n",
    "# note: i is framenumber  \n",
    "def update(i):  \n",
    "    x = np.linspace(0, 2, 1000)  \n",
    "    y = np.sin(2 * np.pi * (x - 0.01 * i))  \n",
    "    line.set_data(x, y)  \n",
    "    return line,  \n",
    "  \n",
    "# call the animator.  blit=True means only re-draw the parts that have changed.  \n",
    "anim = animation.FuncAnimation(fig, update, init_func=init,  \n",
    "                               frames=200, interval=20, blit=False)  \n",
    "  \n",
    "#anim.save('anim3.mp4', fps=30, extra_args=['-vcodec', 'libx264'])  \n",
    "#anim.save('anim3.gif', writer='imagemagick')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 作业1的演示"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import matplotlib.animation as animation\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "def update_point(num):\n",
    "    fig_points.set_data(p2[0][0:num], p2[1][0:num])\n",
    "    fig_points2.set_data(p1[0][1:num], p1[1][1:num])\n",
    "    return fig_points\n",
    "\n",
    "def rotateList(x1, y1, rx, ry, a):\n",
    "    a = math.radians(a)\n",
    "    x2 = [round((x1i-rx)*math.cos(a) - (y1i-ry)*math.sin(a) + rx,4) for (x1i, y1i) in zip(x1, y1)]\n",
    "    y2 = [round((x1i-rx)*math.sin(a) + (y1i-ry)*math.cos(a) + ry,4) for (x1i, y1i) in zip(x1, y1)]\n",
    "    return x2,y2\n",
    "\n",
    "def rotate(x1, y1, rx, ry, a):\n",
    "    a = math.radians(a)\n",
    "    x2 = round((x1-rx)*math.cos(a) - (y1-ry)*math.sin(a) + rx,4)\n",
    "    y2 = round((x1-rx)*math.sin(a) + (y1-ry)*math.cos(a) + ry,4)\n",
    "    return x2,y2\n",
    "\n",
    "def gen_circle_point(n):\n",
    "    ai = 360/(n+1)\n",
    "    if n % 2 == 0:\n",
    "        a = ai * (n-2)/2\n",
    "    else:\n",
    "        a = ai * (n-3)/2\n",
    "        \n",
    "    x, y = 0, 1\n",
    "    flag = 0\n",
    "    p1 = [[],[]]\n",
    "    p2 = [[],[]]\n",
    "    for i in range(0, n+2):\n",
    "        x_old, y_old = x, y\n",
    "        x, y = rotate(x, y, 0, 0, a)\n",
    "        p2[0].append(x)\n",
    "        p2[1].append(y)\n",
    "        p1[0].append((x+x_old)/2)\n",
    "        p1[1].append((y+y_old)/2)\n",
    "        \n",
    "    return (p1, p2)\n",
    "    \n",
    "\n",
    "N=18\n",
    "\n",
    "p1,p2 = gen_circle_point(N-1)\n",
    "# plt.plot(p1[0],p1[1],'b.')\n",
    "# plt.plot(p2[0],p2[1],'r')\n",
    "\n",
    "fig1 = plt.figure()\n",
    "\n",
    "fig_points, = plt.plot([], [], 'r')\n",
    "fig_points2, = plt.plot([], [], 'b.')\n",
    "plt.axis('equal')\n",
    "plt.xlim(-2, 2)\n",
    "plt.ylim(-2, 2)\n",
    "\n",
    "anim = animation.FuncAnimation(fig1, update_point, interval=500)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "np.array()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
